import cv2
import numpy as np 
import os
image = cv2.imread(r'E:\python\data\left03.jpg')
if image is None:
    print("path     wrong")
    try:
        os._exit(0)
    except:
        print('Program is dead.')
print("image ok")
#找到Harris角点
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# gray = np.float32(gray)
# dst = cv2.cornerHarris(gray,2,3,0.04)
# dst = cv2.dilate(dst,None)
# ret, dst = cv2.threshold(dst,0.01*dst.max(),255,0)
# dst = np.uint8(dst)
#
# #找到重心
# ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst)
#
# #定义迭代次数
# criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001)
# corners = cv2.cornerSubPix(gray,np.float32(centroids),(5,5),(-1,-1),criteria)
# #返回角点
# #绘制
# res = np.hstack((centroids,corners))
# res = np.int0(res)
# image[res[:,1],res[:,0]]=[0,0,255]
# image[res[:,3],res[:,2]] = [0,255,0]
#
# cv2.imshow('result',image)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
class HarrisDetector(object):
    def __init__(self):
        # 导数平滑的相邻像素的尺寸
        self.neighbourhood = 3
        # 梯度计算的孔径大小
        self.aperture = 3
        # Harris 参数
        self.k = 0.1
        # 阈值计算的最大强度
        self.maxStrength = 0.0
        # 计算得到的阈值（内部）
        self.threshold = 0.01
        # 非极大值抑制的相邻像素的尺寸
        self.nonMaxSize = 3
        # 非极大值抑制的核
        self.kernel = np.zeros((self.nonMaxSize, self.nonMaxSize) , np.int8)
        # 表示角点强度的32位浮点图像
        self.cornerStrength = None
        # 阈值化之后的32位浮点图像
        self.cornerTh = None
        # 内部局部最大值
        self.localMax = None
    def setLocalMaxWindowSize(self, size):
        self.nonMaxSize = size
        kernel = np.zeros((self.nonMaxSize, self.nonMaxSize) , np.int8)
    def detect(self, image):
        self.cornerStrength = cv2.cornerHarris(image, self.neighbourhood, self.aperture,  self.k)
        cv2.imshow('ini', self.cornerStrength)
        min_val,self.maxStrength,min_indx,max_indx = cv2.minMaxLoc(self.cornerStrength)
        dilated = cv2.dilate(self.cornerStrength,cv2.getStructuringElement(cv2.MORPH_RECT,(3,3)))
        self.localMax = cv2.compare(self.cornerStrength, dilated, cv2.CMP_EQ)
    def getCornerMap(self, qualityLevel):
        self.threshold = qualityLevel * self.maxStrength
        _,self.cornerTh = cv2.threshold(self.cornerStrength, self.threshold, 255, cv2.THRESH_BINARY)
        self.cornerTh = np.array(self.cornerTh)

        self.cornerMap = self.cornerTh.astype(np.uint8)
        result = self.cornerTh.astype(np.uint8)
        cv2.bitwise_and(self.cornerMap, self.localMax, self.cornerMap)

        cv2.bitwise_and(result, self.cornerMap, result)
        cv2.imshow("bitand", result)
        # cv2.waitKey(0)
        # cv2.destroyAllWindows()
    def getCornersMat(self, points, cornerMap):
        for i in range(cornerMap.shape[0]):
            for j in range(cornerMap.shape[1]):
                if cornerMap[i][j]:
                    points.append((j,i))
    def getCorners(self, points, qualityLevel):
        self.getCornerMap(qualityLevel)
        self.getCornersMat(points, self.cornerMap)
        return points
    def drawOnImage(self, image,points, color, radius, thickness):
        print(len(points))
        for i in points:
            print(i)
            cv2.circle(image,i,radius,color,thickness)

harris = HarrisDetector()
harris.detect(gray)
print('harris.detect(gray)')
pts = []
pts = harris.getCorners(pts, 0.05)
print(pts)
harris.drawOnImage(image,pts,(255, 255, 255),3,2)
cv2.imshow("results", image)
cv2.waitKey(0)
cv2.destroyAllWindows()


